package http

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"time"

	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
	"github.com/samber/do/v2"
	"github.com/spf13/viper"
	"go.uber.org/zap"

	"gitee.com/monkeyPP/happy-mall/pkg/log"
	"gitee.com/monkeyPP/happy-mall/pkg/middleware"
	"gitee.com/monkeyPP/happy-mall/services/productservice/internal/interfaces/api/router"
)

// ServerManager HTTP 服务器管理器
type ServerManager struct {
	engine   *gin.Engine
	server   *http.Server
	port     int
	injector do.Injector
}

// NewHTTPServerManager 创建新的 HTTP 服务器管理器
func NewHTTPServerManager(i do.Injector) (*ServerManager, error) {
	gin.SetMode(viper.GetString("runmode"))
	engine := gin.New()

	// 注册 middleware
	mws := []gin.HandlerFunc{gin.Recovery(), middleware.NoCache, middleware.Cors, middleware.Secure, middleware.RequestID()}
	engine.Use(mws...)

	return &ServerManager{
		engine:   engine,
		port:     viper.GetInt("port"),
		injector: i,
	}, nil
}

// RegisterRoutes 注册路由
func (h *ServerManager) RegisterRoutes(registerFunc func(*gin.Engine, do.Injector)) {
	// 注册业务路由
	if registerFunc != nil {
		registerFunc(h.engine, h.injector)
	}

	// 注册管理端点
	h.registerAdminRoutes()
}

// registerAdminRoutes 注册管理路由
func (h *ServerManager) registerAdminRoutes() {
	// 健康检查
	h.engine.GET("/api/v1/product/healthz", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"status":  "ok",
			"service": "product-service",
		})
	})

	// pprof
	runMode := viper.GetString("runmode")
	if runMode != "prod" {
		pprof.Register(h.engine)
	}
}

// Start 启动 HTTP 服务器
func (h *ServerManager) Start() error {
	// 注册默认路由
	h.RegisterRoutes(router.RegisterRoutes)

	// 创建 HTTP 服务器
	h.server = &http.Server{
		Addr:           fmt.Sprintf(":%d", h.port),
		Handler:        h.engine,
		ReadTimeout:    5 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	log.Infow("starting HTTP server", "addr", h.server.Addr, "port", h.port)

	// 启动服务器（这会阻塞）
	if err := h.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
		return fmt.Errorf("failed to start HTTP server: %w", err)
	}
	return nil
}

// Stop 停止 HTTP 服务器
func (h *ServerManager) Stop(ctx context.Context) error {
	if h.server == nil {
		return nil
	}

	log.C(ctx).Infow("stopping HTTP server")

	// 优雅关闭
	if err := h.server.Shutdown(ctx); err != nil {
		log.C(ctx).Errorw("HTTP server shutdown failed", zap.Error(err))
		return err
	}

	log.C(ctx).Infow("HTTP server stopped")
	return nil
}

// GetEngine 获取 Gin 引擎（用于测试）
func (h *ServerManager) GetEngine() *gin.Engine {
	return h.engine
}
